local lvshi = {}
---@param player ServerPlayer @ 发现牌的角色
---@param pattern string[] @发现的规则
---
---
------------------------------------------------------------------------------------------------------@class DIY.CenterAreaRemoveData: CenterAreaRemoveDataSpec, TriggerData
--明置身份
lvshi.RoleShownData = TriggerData:subclass("RoleShownData")

--- TriggerEvent
---@class lvshi.RoleShownDataTriggerEvent: TriggerEvent
---@field public data lvshi.RoleShownData
lvshi.RoleShownDataTriggerEvent = TriggerEvent:subclass("RoleShownDataEvent")

--- 身份明置时
---@class lvshi.BeforeRoleShown: lvshi.RoleShownDataTriggerEvent
lvshi.RoleShown = lvshi.RoleShownDataTriggerEvent:subclass("fk.RoleShown")

--发现牌（暂时只考虑按类别）
--Exppattern:Parse(pattern):match(card)
lvshi.discover = function (player, pattern, n)
  local room = player.room
  if not n then n = 3 end
  n = n + player:getMark("@ls__qizuo_discover")--耦
  local all_cards = table.simpleClone(room.draw_pile)
  table.insertTable(all_cards, room.discard_pile)
  local cards = {}
  table.shuffle(all_cards)
  for _, id in ipairs(all_cards) do
    local card = Fk:getCardById(id)
    if card:getTypeString() == pattern and not table.contains(table.map(cards, function (c) return Fk:getCardById(c).trueName end), card.trueName) then
      table.insertIfNeed(cards, id)
    end
  end
  if #cards < n then return {} end
  cards = table.random(cards, n)
  return cards
end

local function strategylog(player, card, strategy)
  player.room:sendLog{
    type = "#strategyuse",
    from = player.id,
    arg = card:toLogString(),
    arg2 = strategy,
    toast = true,
  }
end

--策略相关

--获取角色的当前策略
---@param player Player @ 角色
---@param wonder_map boolean @ 是否考虑天机图
lvshi.getStrategy = function(player, wonder_map)
  wonder_map = (wonder_map == nil) and true or wonder_map
  if player:hasSkill("#lvshi__wonder_map_skill") and wonder_map then
    return "schemecourage"
  end
  if player:getMark("@!scheme") > 0 then
    return "scheme"
  elseif player:getMark("@!courage") > 0 then
    return "courage"
  elseif player:getMark("@!schemecourage") > 0 then
    return "schemecourage"
  end
  return "none"
end
--获取角色的武将牌上的策略
lvshi.getTrueStrategy = function(player)
  local strategys = {"scheme", "courage", "schemecourage"}
  if Fk.generals[player.general].headnote and table.contains(strategys, Fk.generals[player.general].headnote) then
    return Fk.generals[player.general].headnote
  else
    return "none"
  end
end
--设置角色的策略
lvshi.setStrategy = function(player, strategy)
  player.room:setPlayerMark(player, "@!scheme", 0)
  player.room:setPlayerMark(player, "@!courage", 0)
  player.room:setPlayerMark(player, "@!schemecourage", 0)
  if strategy ~= "none" then
    player.room:setPlayerMark(player, "@!"..strategy, 1)
  end
end
--重置角色的策略至初始状态
lvshi.resetStrategy = function(player)
  lvshi.setStrategy(player, lvshi.getTrueStrategy(player))
end
--令一名角色失去策略（指定或自选）
lvshi.loseStrategy = function(player, strategy)
  local strategys = {}
  if player:getMark("@!scheme") > 0 then
    table.insertIfNeed(strategys, "scheme")
  elseif player:getMark("@!courage") > 0 then
    table.insertIfNeed(strategys, "courage")
  elseif player:getMark("@!schemecourage") > 0 then
    table.insertTable(strategys, {"scheme","courage"})
  end
  if strategy == "choice" then
    strategy = player.room:askToChoice(player, { choices = strategys, skill_name = "loseStrategy" })
  end
  table.removeOne(strategys, strategy)
  player.room:sendLog{type = "#loseStrategy", from = player.id, arg = strategy, toast = true}
  if #strategys == 0 then
    lvshi.setStrategy(player, "none")
  elseif #strategys == 1 then
    lvshi.setStrategy(player, strategys[1])
  else
    lvshi.setStrategy(player, "schemecourage")
  end
end
--令一名角色获得策略
lvshi.gainStrategy = function(player, strategy)
  local strategys = {}
  if player:getMark("@!scheme") > 0 then
    table.insertIfNeed(strategys, "scheme")
  elseif player:getMark("@!courage") > 0 then
    table.insertIfNeed(strategys, "courage")
  elseif player:getMark("@!schemecourage") > 0 then
    table.insertTable(strategys, {"scheme","courage"})
  end
  table.insertIfNeed(strategys, strategy)
  player.room:sendLog{type = "#gainStrategy", from = player.id, arg = strategy, toast = true}
  if #strategys == 0 then
    lvshi.setStrategy(player, "none")
  elseif #strategys == 1 then
    lvshi.setStrategy(player, strategys[1])
  else
    lvshi.setStrategy(player, "schemecourage")
  end
end

---@param player ServerPlayer @ 使用牌的角色
---@param card Card @ 使用的策略牌
---@param scheme String 智策略效果
---@param courage String 勇策略效果

--智勇策略
lvshi.strategytrickuse = function (player, card, scheme, courage)
  if card:isVirtual() and not card.canstrategy then return "nonstrategy" end
  local choices = {"nonstrategy"}
  if string.find(lvshi.getStrategy(player), "scheme") then table.insert(choices, scheme) end
  if string.find(lvshi.getStrategy(player), "courage") then table.insert(choices, courage) end
  local choice = player.room:askToChoice(player, {choices = choices,
   skill_name = card.name,
   detailed = true,
  })
  local strategy = "none"
  if choice == scheme then
    strategy = "scheme"
  elseif choice == courage then
    strategy = "courage"
  end
  if strategy ~= "none" then
    strategylog(player, card, strategy)
  end
  return choice
end

Fk:loadTranslationTable{
  ["scheme"] = "<font color=\"#1F51FF\"><b>智策略</b></font>",
  ["courage"] = "<font color=\"#D2042D\"><b>勇策略</b></font>",
  ["schemecourage"] = "<font color=\"#BF40BF\"><b>智勇策略</b></font>",
  ["nonstrategy"] = "无策略",
  ["#strategyuse"] = "%from 发动了 %arg 的 %arg2 效果",

  ["loseStrategy"] = "失去策略",
  ["#loseStrategy"] = "%from 失去 %arg",
  ["#gainStrategy"] = "%from 获得 %arg",
}

lvshi.isFriend = function(player, target, role_shown)
  if role_shown == nil then role_shown = false end
  if player == target then return true end
  if player.role == "renegade" then return false end
  if (player.role_shown and target.role_shown) or role_shown then
    return player.role == target.role or
    (table.contains({"lord", "loyalist"}, player.role) and table.contains({"lord", "loyalist"}, target.role))
    or (table.contains({"rebel", "rebel_chief"}, player.role) and table.contains({"rebel", "rebel_chief"}, target.role))
  end
  return false
end
--数花色
lvshi.countSuits = function(cards)
  local suits = {}
  for _, id in ipairs(cards) do
    if Fk:getCardById(id).suit ~= Card.NoSuit then
      table.insertIfNeed(suits, Fk:getCardById(id).suit)
    end
  end
  return #suits
end
--数类别
lvshi.countTypes = function(cards, is_subtype)
  if not is_subtype then is_subtype = false end
  local types = {}
  for _, id in ipairs(cards) do
    if is_subtype then
      table.insertIfNeed(types, Fk:getCardById(id).sub_type)
    else
      table.insertIfNeed(types, Fk:getCardById(id).type)
    end
  end
  return #types
end

--双面将翻面
lvshi.turnOvertochange = function (player, skill)
  local isDeputy = false
  if player.deputyGeneral ~= "" and table.contains(Fk.generals[player.deputyGeneral]:getSkillNameList(), skill.name) then
    isDeputy = true
  end
  if table.contains(Fk.generals[player.general]:getSkillNameList(), skill.name) then
    isDeputy = false
  end
  local hero = Fk.generals[player.general].back
  if isDeputy then
    hero = Fk.generals[player.deputyGeneral].back
  end
  player.room:changeHero(player, hero, false, isDeputy, true, false)
end

--- 获得一张**实体牌**最后一次离开【手牌区+装备区】进入非角色区域时位于谁的区域
---@param room Room @ 房间
---@param card Card | integer @ **实体牌**或其ID
---@return ServerPlayer? @ 最后区域使用者，若无则表示此牌从未如此离开过
lvshi.getCardLastOwner = function(room, card)
  local logic = room.logic
  local cid = Card:getIdList(card)[1]
  local last_owner = room:getCardOwner(cid) ---@cast last_owner ServerPlayer
  if last_owner then return last_owner end
  logic:getEventsByRule(GameEvent.MoveCards, 1, function(e)
    for _, move in ipairs(e.data) do
      if move.to == nil and move.from then
        for _, info in ipairs(move.moveInfo) do
          if info.cardId == cid and table.contains({ Player.Hand, Player.Equip }, info.fromArea) then
            last_owner = move.from
            return true
          end
        end
      end
    end
  end, 0)
  return last_owner
end


return lvshi